#include <opencv2/opencv.hpp>
#include <opencv2/ximgproc.hpp>




#include <ctype.h>
#include <stdio.h>
#include <iostream>

using namespace cv;
using namespace cv::ximgproc;
using namespace std;

static const char* window_name = "SLIC Superpixels";

static const char* keys =
"{h help      | | help menu}"
"{c camera    |0| camera id}"
"{i image     | | image file}"
"{a algorithm |1| SLIC(0),SLICO(1),MSLIC(2)}"
;

#if 0
int main(int argc, char** argv)
{
    int algorithm = 0;
    int region_size = 15;
    int ruler = 30;
    int min_element_size = 50;
    int num_iterations = 3;

    string imageName = "./img/1.jpg";
    Mat input_image = imread(imageName, 1);
    cv::resize(input_image, input_image, cv::Size(940, 480), 0, 0, CV_INTER_LINEAR);
    if (input_image.empty())
    {
        cout << "Could not open image..." << imageName << "\n";
        return -1;
    }

    namedWindow(window_name, 0);
    createTrackbar("Algorithm", window_name, &algorithm, 2, 0);
    createTrackbar("Region size", window_name, &region_size, 200, 0);
    createTrackbar("Ruler", window_name, &ruler, 100, 0);
    createTrackbar("Connectivity", window_name, &min_element_size, 100, 0);
    createTrackbar("Iterations", window_name, &num_iterations, 12, 0);

    Mat result, mask;
    int display_mode = 0;

    for (;;)
    {
        Mat frame;
        input_image.copyTo(frame);

        if (frame.empty())
            break;

        result = frame;
        Mat converted;
        cvtColor(frame, converted, COLOR_BGR2HSV);

        double t = (double)getTickCount();

        Ptr<SuperpixelSLIC> slic = createSuperpixelSLIC(converted, SLIC, region_size, float(ruler));
        slic->iterate(num_iterations);
        if (min_element_size > 0)
            slic->enforceLabelConnectivity(min_element_size);

        t = ((double)getTickCount() - t) / getTickFrequency();
        cout << "SLIC" << (algorithm ? 'O' : ' ')
            << " segmentation took " << (int)(t * 1000)
            << " ms with " << slic->getNumberOfSuperpixels() << " superpixels" << endl;

        // get the contours for displaying
        slic->getLabelContourMask(mask, true);
        result.setTo(Scalar(0, 255, 0), mask);

        // display output
        switch (display_mode)
        {
        case 0: //superpixel contours
            imshow(window_name, result);
            break;
        case 1: //mask
            imshow(window_name, mask);
            break;
        case 2: //labels array
        {
            // use the last x bit to determine the color. Note that this does not
            // guarantee that 2 neighboring superpixels have different colors.
            // retrieve the segmentation result
            Mat labels;
            slic->getLabels(labels);
            const int num_label_bits = 2;
            labels &= (1 << num_label_bits) - 1;
            labels *= 1 << (16 - num_label_bits);
            imshow(window_name, labels);
            break;
        }
        }

        int c = waitKey(1) & 0xff;
        if (c == 'q' || c == 'Q' || c == 27)
            break;
        else if (c == ' ')
            display_mode = (display_mode + 1) % 3;
    }

    return 0;
}
#endif

int main(int argc, char** argv)
{
    Mat input_image = imread("./img/1.jpg", 1);
    Mat converted;
    cvtColor(input_image, converted, COLOR_BGR2HSV);

    {
        int region_size = 15;
        int ruler = 30;
        int min_element_size = 50;
        int num_iterations = 3;

        Mat mask;
        Mat result;

        result = input_image;

        Ptr<SuperpixelSLIC> slic = createSuperpixelSLIC(converted, SLIC, region_size, float(ruler));
        slic->iterate(num_iterations);
        slic->enforceLabelConnectivity(min_element_size);

        cout << "SLIC" << slic->getNumberOfSuperpixels() << " superpixels" << endl;

        // get the contours for displaying
        slic->getLabelContourMask(mask, true);
        result.setTo(Scalar(0, 255, 0), mask);

        imshow("SLIC", result);
    }

    {
        int region_size = 15;
        int min_element_size = 50;
        int num_iterations = 3;

        Mat mask;
        Mat result;

        result = input_image;

        Ptr<SuperpixelLSC> lsc = createSuperpixelLSC(converted, region_size);
        lsc->iterate(num_iterations);
        lsc->enforceLabelConnectivity(min_element_size);

        cout << "LSC" << lsc->getNumberOfSuperpixels() << " superpixels" << endl;

        // get the contours for displaying
        lsc->getLabelContourMask(mask, true);
        result.setTo(Scalar(0, 255, 0), mask);

        imshow("LSC", result);
    }

    {
        int width = input_image.size().width;
        int height = input_image.size().height;
        int num_iterations = 4;
        int prior = 2;
        bool double_step = false;
        int num_superpixels = 400;
        int num_levels = 4;
        int num_histogram_bins = 5;

        Mat mask;
        Mat result;

        result = input_image;

        Ptr<SuperpixelSEEDS> seeds = createSuperpixelSEEDS(width, height, converted.channels(), num_superpixels,
            num_levels, prior, num_histogram_bins, double_step);
        seeds->iterate(converted, num_iterations);

        cout << "SEEDS" << seeds->getNumberOfSuperpixels() << " superpixels" << endl;

        // get the contours for displaying
        seeds->getLabelContourMask(mask, true);
        result.setTo(Scalar(0, 255, 0), mask);

        imshow("SEEDS", result);
    }

    cv::waitKey(0);
    return 0;
}